/*********************************************************/
/**					system.h by doom119					 */
/**						April, 2010						 */
/*********************************************************/
#ifndef _SYSTEM_H_
#define _SYSTEM_H_

#include "descriptor.h"

#define move_to_user_mode() \
	__asm__("movl %%esp, %%eax\n\t" \
			"pushl $0x17\n\t" \
			"pushl %%eax\n\t" \
			"pushfl \n\t" \
			"pushl $0x0f\n\t" \
			"pushl $1f\n\t" \
			"iret\n\t" \
			"1: movl $0x17, %%eax\n\t" \
			"movw %%ax, %%ds\n\t" \
			"movw %%ax, %%es\n\t" \
			"movw %%ax, %%fs\n\t" \
			"movw %%ax, %%gs\n\t" \
			:::"ax")

#define sti() __asm__("sti"::);
#define cli() __asm__("cli"::);
#define nop() __asm__("nop"::);
#define iret() __asm__("iret"::);

#define set_gate(idt_n, type, cpl, addr) \
__asm__("movw %%dx, %%ax\n\t" \
		"movl %%eax, %1\n\t" \
		"movw %0, %%dx\n\t" \
		"movl %%edx, %2\n\t" \
		: \
		:"i"((short)((cpl<<13)+(type<<8)+0x8000)), \
		"o"(*(char*)idt_n), \
		"o"(*(4+((char*)idt_n))), \
		"d"((char*)addr), "a"(0x80000))

#define set_interrupt_gate(nr, addr) \
	set_gate(&_idt[nr], 14, 0, addr)

#define set_trap_gate(nr, addr) \
	set_gate(&_idt[nr], 15, 0, addr)

#define set_user_trap_gate(nr, addr) \
	set_gate(&_idt[nr], 15, 3, addr)

#endif
